/*
 * This file is part of quickReminder, a software for gamers
 *
 * Copyright (C) 2006-2008 Lucas Romero
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Collections.Specialized;
using LucasCode;
using LucasCode.Tools;
using ESLReminder;
using System.Diagnostics;
using System.Threading;
using BalloonCS;
using XPTable;
using XPTable.Models;
using LucasCode.Win32;
using XPTable.Editors;

namespace quickReminder
{
    public partial class FormUpload : Form
    {
        string m_Cookie = string.Empty;
        //int m_GameVersion = 1;
        //ConsoleEventItemCollection consoleevents;
        StringCollection MapsPlayed = new StringCollection();
        MatchArchive m_Archive = new MatchArchive();
        public FormUpload(string archive)
        {
            InitializeComponent();
            m_Archive = new MatchArchive(archive);
            createArchiveToolStripMenuItem.Visible = false;
            InitDialog();
           
            RefreshView();
        }


        public FormUpload(string MatchURL,string cookie, StringCollection FileList,ConsoleEventItemCollection events, string Gamename, string Modname)
        {
            InitializeComponent();
            m_Archive.Matchlink = MatchURL;
            InitDialog();
            
            Text += " - " + MatchURL;
            

            

            //m_GameVersion = gamever;
#if TEST_PLAYERPARSING && DEBUG
            m_Archive.Matchlink = "http://www.esl.eu/de/cs/5on5/mr12/ladder/match/8510087/";

            MatchPlayer p = new MatchPlayer("Chronicz");
            p.GameID = "0:0:11849927";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("paiN");
            p.GameID = "0:1:15823874";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("oLos");
            p.GameID = "0:1:9929224";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("HansDampf");
            p.GameID = "0:1:439954";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("evoexe");
            p.GameID = "0:1:3222719";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("Hoax");
            p.GameID = "0:0:291986";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("ruffoR");
            p.GameID = "0:0:6888909";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("tOrE");
            p.GameID = "0:1:9870342";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("HelD");
            p.GameID = "0:0:11647288";
            m_Archive.AddTeamlessPlayer(p);

            p = new MatchPlayer("Joe");
            p.GameID = "0:0:3654325";
            m_Archive.AddTeamlessPlayer(p);

            //RefreshView();

            /*ListViewItem p1 = new ListViewItem("bla", 0);
            p1.SubItems.Add("0:1:10936068");
            p1.SubItems.Add("");
            p1.SubItems.Add("");
            p1.SubItems.Add("none");
            //i.SubItems[4].Tag = "2507797";

            ListViewItem p2 = new ListViewItem("bla", 0);
            p2.SubItems.Add("0:1:1663189");
            p2.SubItems.Add("");
            p2.SubItems.Add("");
            p2.SubItems.Add("none");

            PlayerList.Items.Add(p1);
            PlayerList.Items.Add(p2);*/
            //PlayerList.Items.Add(p3);
#endif
            if (Properties.Settings.Default.UploadWindowSize.Height > 0 && Properties.Settings.Default.UploadWindowSize.Width > 0)
                this.Size = Properties.Settings.Default.UploadWindowSize;
            /*
            if (Properties.Settings.Default.UploadWindowPos.X >= 0 && Properties.Settings.Default.UploadWindowPos.Y >= 0)
                this.Location = Properties.Settings.Default.UploadWindowPos;*/
            //splitContainer1.SplitterDistance = Properties.Settings.Default.UploadWindowSplitterPos;
            
            //ParseConsole(events);
            m_Archive.Gamename = Gamename;
            m_Archive.Modname = Modname;
            m_Archive.Matchlink = MatchURL;


#if DEBUG || READEVENTSFROMFILE
            if (events.Count <= 0 && File.Exists("condumphl1.txt"))
            {

                StreamReader reader = new StreamReader("condumphl1.txt");
                while (!reader.EndOfStream)
                {
                    events.Add(new ConsoleEventItem(DateTime.Now, ConsoleEventItemType.None, reader.ReadLine()));
                }
                reader.Close();
            }
#endif
            if (!string.IsNullOrEmpty(m_Archive.Gamename))
            {
                switch (m_Archive.Gamename.ToLower())
                {
                    case "hl":
                        ConsoleParserHL1 p = new ConsoleParserHL1();
                        p.Parse(events);
                        m_Archive.TeamlessPlayers = p.Players;
                        break;
                    case "hl2":
                        ConsoleParserHL2 hl2p = new ConsoleParserHL2();
                        hl2p.Parse(events);
                        m_Archive.TeamlessPlayers = hl2p.Players;
                        break;
                }
            }
#if DEBUG || READEVENTSFROMFILE
            else
            {
                ConsoleParserHL1 p = new ConsoleParserHL1();
                p.Parse(events);
                m_Archive.TeamlessPlayers = p.Players;
            }
#endif

            foreach (string s in FileList)
                m_Archive.AddFile(new MatchFile(s));

            m_Archive.AutoRenameFiles(events, new MatchArchive.ParseSettings(Properties.Settings.Default.AequitasTitle, Properties.Settings.Default.DemoVariationpercent));
            
            RefreshView();
        }

        private void InitDialog()
        {
            Parser.DoWork += new DoWorkEventHandler(Parser_DoWork);
            MatchInfoUpdater.DoWork += new DoWorkEventHandler(Parser_DoWork);
            m_Archive.ProgressChanged += new EventHandler(m_Archive_ProgressChanged);
            m_Archive.FileStatusChanged += new EventHandler<FileStatusChangedEventArgs>(m_Archive_FileStatusChanged);
            m_Archive.UploadComplete += new EventHandler(m_Archive_UploadComplete);
            m_Cookie = Properties.Settings.Default.Cookie;
            m_Archive.LoginCookie = Properties.Settings.Default.Cookie;
            if (string.IsNullOrEmpty(m_Archive.Matchlink))
                tabControl1.TabPages.Remove(tabOverview);
        }
        
        private void m_Archive_UploadComplete(object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler(m_Archive_UploadComplete), new object[] { sender, e });
                return;
            }
            //UploadProgress.Visible = false;
            UploadStatusText.Text = "Uploader idle.";
            startUploadToolStripMenuItem1.Visible = true;
            cancelAllUploadsToolStripMenuItem.Visible = false;
            cancelSelectedUploadsToolStripMenuItem.Visible = false;
            //UploadStatusText.Visible = false;
            //lwFileList.CheckBoxes = true;
            cbUpload.Enabled = true;
            xpFiles.BeginUpdate();
            foreach (Row row in xpFiles.TableModel.Rows)
            {
                if (row.Tag == null)
                    continue;
                MatchFile f = row.Tag as MatchFile;
                if (row.Cells[0].Checked)
                {
                    row.Editable = true;
                    if (f.WasUploaded)
                    {
                        row.Cells[1].Image = lang.apply16;
                        row.Cells[0].Checked = false;

                    }
                    else
                    {
                        row.Cells[1].Image = lang.button_cancel;
                    }
                }
                
            }
            xpFiles.EndUpdate();
            startUploadToolStripMenuItem.Enabled = true;
        }

        private void m_Archive_FileStatusChanged(object sender, FileStatusChangedEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<FileStatusChangedEventArgs>(m_Archive_FileStatusChanged), new object[] { sender, e });
                return;
            }
            xpFiles.BeginUpdate();
            foreach (Row r in xpFiles.TableModel.Rows)
                if (r.Tag == e.File)
                    UpdateFileRow(r);
            xpFiles.EndUpdate();
        }

        private void UpdateFileRow(Row r)
        {
            MatchFile file = r.Tag as MatchFile;
            r.Cells[4].Text = file.Status;
            r.Cells[5].Data = file.Progress;
            r.Cells[6].Text = file.Speed.ToString() + "kb/s";
        }


        void m_Archive_ProgressChanged(object sender, EventArgs e)
        {
            if(InvokeRequired)
            {
                this.BeginInvoke(new EventHandler(m_Archive_ProgressChanged), new object[] { sender, e });
                return;
            }
            WorkProgress.Value = m_Archive.Progress;
        }


    /*public delegate void UpdateStatsInvoker(List<MatchPlayer> players);

        private void UpdateStats(List<MatchPlayer> players)
        {
            if(InvokeRequired)
            {
                this.BeginInvoke(new UpdateStatsInvoker(UpdateStats), new object[] { players });
                return;
            }*/

        private Image GetMapImage(string map, string game)
        {
            try
            {
                if (File.Exists(Path.Combine(Path.Combine("maps", game), map + ".jpg")))
                    return Image.FromFile(Path.Combine(Path.Combine("maps", game), map + ".jpg"));
                System.Resources.ResourceManager res = new System.Resources.ResourceManager("quickReminder.maps" + game.ToLower(), GetType().Assembly);
                return (Image)res.GetObject(map);
            }
            catch
            {
                return null;
            }
        }

        public delegate void RefreshViewInvoker();

        private void RefreshView()
        {
            if (InvokeRequired)
            {
                BeginInvoke(new RefreshViewInvoker(RefreshView));
                return;
            }
            MatchArchive archive = m_Archive;
            if (!string.IsNullOrEmpty(archive.Filename))
                this.Text = Path.GetFileName(archive.Filename);
            else if (!string.IsNullOrEmpty(archive.Matchlink))
                this.Text = archive.Matchlink;
            else
                this.Text = "Match Overview";
            if (archive.Contestants.Length > 0)
                this.Text += " - " + archive.Contestants[0].Name;
            if (archive.Contestants.Length > 1)
                this.Text += " vs " + archive.Contestants[1].Name;

            if (archive.Contestants.Length > 0)
            {
                if (archive.Contestants[0].Type == MatchContestantTypes.Individual)
                    Logo1.Height = 133;
                else
                    Logo1.Height = 100;
                Logo1.Image = archive.Contestants[0].Logo;
                Logo1.Tag = archive.Contestants[0].URL;

                lTeam1Name.Text = archive.Contestants[0].Name;

                if (archive.Contestants[0] == archive.Winner)
                    lTeam1Name.ForeColor = Color.Green;
                else if (archive.Winner != null)
                    lTeam1Name.ForeColor = Color.Red;
                else
                    lTeam1Name.ForeColor = SystemColors.ControlText;

                if (archive.Contestants.Length > 1)
                {
                    if (archive.Contestants[1].Type == MatchContestantTypes.Individual)
                        Logo2.Height = 133;
                    else
                        Logo2.Height = 100;
                    Logo2.Image = archive.Contestants[1].Logo;
                    Logo2.Tag = archive.Contestants[1].URL;
                    lTeam2Name.Text = archive.Contestants[1].Name;

                    if (archive.Contestants[1] == archive.Winner)
                        lTeam2Name.ForeColor = Color.Green;
                    else if (archive.Winner != null)
                        lTeam2Name.ForeColor = Color.Red;
                    else
                        lTeam2Name.ForeColor = SystemColors.ControlText;

                }
            }
            if (archive.Rounds.Length > 0)
            {
                s1.Text = archive.Rounds[0].Scores[0].ToString();
                s2.Text = archive.Rounds[0].Scores[1].ToString();
                lMap1.Text = archive.Rounds[0].Map;
                pMap1.Image = GetMapImage(archive.Rounds[0].Map, m_Archive.Gamename);
                //if (File.Exists(Path.Combine("maps", archive.Rounds[0].Map + ".jpg")))
                    //pMap1.LoadAsync(Path.Combine("maps", archive.Rounds[0].Map + ".jpg"));
                //else
                    //pMap1.Image = (Bitmap)LucasCode.Properties.Resources.ResourceManager.GetObject(lMap1.Text);
                if (archive.Rounds.Length > 1)
                {
                    s3.Visible = true;
                    s4.Visible = true;
                    //label3.Visible = true;
                    lMap2.Visible = true;
                    pMap2.Visible = true;
                    s3.Text = archive.Rounds[1].Scores[0].ToString();
                    s4.Text = archive.Rounds[1].Scores[1].ToString();
                    lMap2.Text = archive.Rounds[1].Map;


                    pMap2.Image = GetMapImage(archive.Rounds[1].Map, m_Archive.Gamename);
                    //if (File.Exists(Path.Combine("maps", archive.Rounds[1].Map + ".jpg")))
                        //pMap1.LoadAsync(Path.Combine("maps", archive.Rounds[1].Map + ".jpg"));
                    //else
                        //pMap2.Image = (Bitmap)LucasCode.Properties.Resources.ResourceManager.GetObject(lMap2.Text);
                }
                else
                {
                    s3.Visible = false;
                    s4.Visible = false;
                    //label3.Visible = false;
                    lMap2.Visible = false;
                    pMap2.Visible = false;
                }
            }
            if (!tabControl1.TabPages.Contains(tabOverview) && !string.IsNullOrEmpty(m_Archive.Matchlink))
                tabControl1.TabPages.Add(tabOverview);
            RefreshFileList();
            
            UpdateStats(m_Archive.Players);
        }

        private void RefreshFileList()
        {
            xpFiles.TableModel.Rows.Clear();
            foreach (MatchFile f in m_Archive.Files)
            {
                xpFiles.TableModel.Rows.Add(getFileRow(f));
            }
        }

        private Row getFileRow(MatchFile f)
        {
            Row r = new Row();

            r.Cells.Add(new Cell(string.Empty, !f.WasUploaded && f.WasAutoRenamed && (f.FileType == MatchFileType.Screenshot || f.FileType == MatchFileType.Aequitas)));
            r.Cells.Add(new Cell(string.Empty, Shell32.GetFiletypeIcon(f.Filename, false)));

            r.Cells[r.Cells.Count - 1].ImageSizeMode = ImageSizeMode.Normal;
            r.Cells.Add(new Cell(f.TargetName, lang.about_16));
            //ListViewItem i = new ListViewItem(name);
            r.Cells[r.Cells.Count - 1].Tag = f;
            r.Tag = f;

            //i.ToolTipText = Path.GetFileName(s);
            r.Cells.Add(new Cell(getFormattedKiloBytes(f.Size) + "kB"));

            r.Cells.Add(new Cell("Idle")); //Status 2
            r.Cells.Add(new Cell()); //Progress 3
            r.Cells.Add(new Cell()); //Speed 4
            //r.Cells.Add(new Cell()); //Time Remaining 5
            return r;
        }

        private void Parser_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                m_Archive.CompleteUpdate(m_Cookie);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            //ThreadPool.QueueUserWorkItem(new WaitCallback(ParsePlayers), e.Argument);
#if !DEBUG
            //ParsePlayers(e.Argument);
#endif
        }

        private MatchPlayer GetPlayer(List<MatchPlayer> players,  string name)
        {
            foreach (MatchPlayer p in players)
            {
                if (p.CurrentNick == name)
                {
                    return p;
                }
            }
            MatchPlayer pl = new MatchPlayer(name);
            players.Add(pl);
            return pl;
        }


        public delegate void UpdateStatsInvoker(MatchPlayer[] players);

        private void UpdateStats(MatchPlayer[] players)
        {
            if(InvokeRequired)
            {
                this.BeginInvoke(new UpdateStatsInvoker(UpdateStats), new object[] { players });
                return;
            }
            xpStatistics.BeginUpdate();
            StatTableTM.Rows.Clear();
            //xpStatistics.SuspendLayout();
            foreach (MatchPlayer p in players)
            {
                Row r = new Row();
                r.Tag = p;
                if (p.IsBarred)
                    r.BackColor = Color.MistyRose;
                Cell c = new Cell(p.CurrentNick, lang.user16);
                c.ToolTipText = String.Join(Environment.NewLine, p.Names);
                c.WordWrap = false;
                r.Cells.Add(c);
                r.Cells.Add(p.GameID);
                if (!string.IsNullOrEmpty(p.ESLNick))
                {
                    c = new Cell(p.ESLNick);
                    c.Tag = p.UserID;
                    r.Cells.Add(c);
                }
                else
                    r.Cells.Add("<n/a>");

                c = new Cell("");
                c.ImageSizeMode = ImageSizeMode.ScaledToFit;
                if (!string.IsNullOrEmpty(m_Archive.Matchlink))
                {
                    if (p.HasAequitasLog)
                    {
                        c.Image = lang.aequitas16;
                        c.ToolTipText = "aequitas log available";
                    }
                    else
                    {
                        c.Image = lang.noaequitas16;
                        c.ToolTipText = "No aequitas log found!";
                    }
                }
                r.Cells.Add(c);
                    
                r.Cells.Add(new Cell(p.Kills));
                r.Cells.Add(new Cell(p.Headshots));
                if (p.Kills > 0)
                    r.Cells.Add(new Cell((int)Math.Round(((double)p.Headshots / p.Kills) * 100)));
                else
                    r.Cells.Add(new Cell(0));
                r.Cells.Add(new Cell(p.Deaths));
                //if (p.Deaths > 0)

                if (p.Deaths > 0)
                    r.Cells.Add(new Cell(Convert.ToString(Math.Round((double)p.Kills / p.Deaths, 2))));
                else if (p.Kills <= 0)
                    r.Cells.Add("");
                else
                    r.Cells.Add("∞");
                //else
                //r.Cells.Add(new Cell(double.PositiveInfinity.ToString()));
                StatTableTM.Rows.Add(r);
                //Row subrow = 
                
                //r.SubRows.Add(GetPlayerDetailsRow(p));
                //r.ExpandSubRows = false;
                //r.SubRows.Add(new Row(new string[] { "0", "0", "0" }));
            }
            xpStatistics.EndUpdate();
            //xpStatistics.ResumeLayout();
        }

        private Row GetPlayerDetailsRow(MatchPlayer p)
        {
            Row r = new Row();
            r.BackColor = Color.WhiteSmoke;
            r.Cells.Add(new Cell());
            string nickinfo = "All Nicks: ";
            foreach (string s in p.Names)
            {
                nickinfo += s + " / ";
            }
            Cell c = new Cell(nickinfo);
            c.ColSpan = 6;
            r.Cells.Add(c);
            return r;
        }

        private string FromHL2String(string input)
        {
            UTF8Encoding u = new UTF8Encoding();
            //Encoding e = Encoding.GetEncoding(1252);
            Encoding e = Encoding.GetEncoding(1252);
            return u.GetString(e.GetBytes(input));
        }

        /*private void ParseConsoleHL2()
        {
            try
            {
                using (StreamWriter w = new StreamWriter("condumphl2.txt"))
                {
                    foreach (ConsoleEventItem ev in consoleevents)
                    {
                        w.WriteLine(ev.EventText);
                    }
                    w.Close();
                }
            }
            catch { }
        }*/

        /*private void Parser_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ParseStatus status = (ParseStatus)e.UserState;
            switch(status)
            {
                case ParseStatus.Init:      ShowProgress(true);
                    break;
            }
        }*/
        private void ShowProgress(bool visible)
        {
            //if (ParseProgress.InvokeRequired)
            //{
                //Invoke(new MethodShowProgress(ShowProgress), new Object[] { true });
               /* Invoke(new MethodTreeViewTreeNode(AddRootNode),
                        new Object[] { tv, tn });*/
                //return;
            //}
            //ParseProgress.Visible = visible;
        }
        protected delegate void MethodShowProgress(bool val);

        /*void ParsePlayers(object data)
        {
           
            //try
            //{
                string HTML = string.Empty;
                ParseStatusText.Visible = true;
                //ParseProgress.Visible = true;

                
                
                
                //StatusMenu.Visible = true;
                //StatusMenu.Invalidate();
                //statusStrip1.PerformLayout();
                //Parser.ReportProgress(0, ParseStatus.Init);
                string UserRegex = string.Empty;
                string HL1Regex = @"#\s*\d+\s+""(.+?)""\s+\d+\s+STEAM_(\d+:\d+:\d+)(\s+\d+\s+\d+:\d+\s+\d+\s+\d+\s*(\d+.\d+.\d+.\d+))*";
                string HL2Regex = @"#\s*\d+\s+""(.+?)""\s+STEAM_(\d+:\d+:\d+)\s+\d\d:\d\d\s+\d+\s+\d+\s+\w+(\s+\d+\s+\d+:\d+\s+\d+\s+\d+\s*(\d+.\d+.\d+.\d+))*";
                if (m_GameVersion == 1)
                    UserRegex = HL1Regex;
                else if(m_GameVersion == 2)
                    UserRegex = HL2Regex;
                foreach (ConsoleEventItem ev in consoleevents)
                {
                    if (ev.EventType != ConsoleEventItemType.StatusScreenshotTaken && ev.EventType != ConsoleEventItemType.None)
                        continue;
                    //Debug.WriteLine("<ConsoleEvent>" + ev.EventText + "</ConsoleEvent>");
                    foreach (Match m in Regex.Matches(ev.EventText, UserRegex))
                    {
                        bool exists = false;
                        foreach (ListViewItem i in PlayerList.Items)
                        {
                            //SteamID is already in list
                            if (i.SubItems[1].Text == m.Groups[2].Value)
                            {
                                exists = true;
                                if (!i.SubItems[2].Text.Contains(m.Groups[4].Value))
                                {
                                    if (i.SubItems[2].Text != String.Empty)
                                        i.SubItems[2].Text += ", ";
                                    i.SubItems[2].Text += m.Groups[4].Value;
                                }
                                if (!i.Text.Contains(m.Groups[1].Value))
                                {
                                    i.Text += ", " + m.Groups[1].Value;
                                }
                            }
                        }
                        if (!exists)
                        {
                            //Debug.WriteLine("Line matches!");
                            ListViewItem i = new ListViewItem(m.Groups[1].Value, 0);
                            i.SubItems.Add(m.Groups[2].Value);
                            i.SubItems.Add(m.Groups[4].Value);
                            i.SubItems.Add("");
                            i.SubItems.Add("none");
                            PlayerList.Items.Add(i);
                        }
                        //w.WriteLine(String.Format("User: {0} SteamID: {1} IP: {2}", m.Groups[1].Value, m.Groups[2].Value, m.Groups[3].Value));
                    }
                }


                string MatchText = "nix";
                MatchCollection AeqRegex = null;
                int foundusers = 0;
                if (!string.IsNullOrEmpty(m_Archive.Matchlink))
                {
                    ParseStatusText.Text = lang.ParsingMatch;
                    MatchText = ESLHelpers.GetHTML(m_Archive.Matchlink, string.Empty);

                    MapsPlayed.Clear();
                    Match MapRegex1 = Regex.Match(MatchText, @"<td.*?>Contestants</td>\s*<td.*?>Parameters</td>.*?<td.*?>map</td>\s*<td.*?>(.*?)</td>", RegexOptions.Singleline);
                    Match MapRegex2 = Regex.Match(MatchText, @"Result</td>.*?(?:<tbody>|<table.*?>).*?<tr>.*?<td.*?>(.*?)</td>.*?</tr>.*?<tr>.*?<td.*?>(.*?)</td>", RegexOptions.Singleline);
                    if (MapRegex1.Success)
                        MapsPlayed.Add(MapRegex1.Groups[1].Value);
                    else if (MapRegex2.Success)
                    {
                        MapsPlayed.Add(MapRegex2.Groups[1].Value);
                        MapsPlayed.Add(MapRegex2.Groups[2].Value);
                    }
                    AeqRegex = Regex.Matches(MatchText, @"<a href="".*?/player/(\d+?)/"".*?>(.*?)</a></td>\s*<td.*?><a href="".*?/team/\d*?/"".*?>.*?</a></td>\s*<td.*?>Logfile available.</td>",RegexOptions.Singleline);
                    
                    MatchCollection TeamRegex = Regex.Matches(MatchText,
@"<a href=""(.*?/(team|player)/\d+/)""><img src=""http://www.eslgfx.net/gfx/logos/.*?\.jpg"".*?><br>(.+?)</a>");
                    if (TeamRegex.Count >= 2)
                    {
                        Text = TeamRegex[0].Groups[3].Value + " vs. " + TeamRegex[1].Groups[3].Value;
                        if(TeamRegex[0].Groups[2].Value == "team")
                        {
                            PlayerList.Groups.Add("team1", TeamRegex[0].Groups[3].Value);
                            PlayerList.Groups.Add("team2", TeamRegex[1].Groups[3].Value);
                        }
                    }
                    int team = 0;
                    foreach (Match m in TeamRegex)
                    {
                        if (m.Groups[2].Value == "team")
                        {
                            ParseStatusText.Text = String.Format(lang.ParsingTeam, m.Groups[3].Value);
                            ListViewGroup grp = PlayerList.Groups.Add(String.Format("team{0}", team), m.Groups[3].Value);
                            string Teamsheet = ESLHelpers.GetHTML("http://www.esl.eu" + m.Groups[1].Value.Replace("/team/", "/team/members/"), string.Empty);

                            foreach (Match m2 in Regex.Matches(Teamsheet, @"<a href=""(\S*?/player/(\d+)/)"">(.*?)</a>.*?<td.*?>\d+ days</td>.*?<div>.*?</td>", RegexOptions.Singleline))
                            {
                                foreach (Match m3 in Regex.Matches(m2.Value, @"<div>(.+?):\s+(\S+?)\s+", RegexOptions.Singleline))
                                {
                                    if (m3.Groups[1].Value == idname)
                                        foreach (ListViewItem i in PlayerList.Items)
                                        {
                                            if (m3.Groups[2].Value == i.SubItems[1].Text)
                                            {
                                                foundusers++;
                                                i.SubItems[3].Text = m2.Groups[3].Value;
                                                i.SubItems[3].Tag = m2.Groups[2].Value;
                                                i.SubItems[4].Text = m.Groups[3].Value;
                                                i.ImageIndex = 1;
                                                i.Group = grp;
                                                bool aeqfound = false;
                                                foreach (Match m4 in AeqRegex)
                                                {
                                                    if(m4.Groups[1].Value == m2.Groups[2].Value)
                                                    {
                                                        //ids match
                                                        aeqfound = true;
                                                    }
                                                }
                                                if(!aeqfound)
                                                {
                                                    i.BackColor = Color.Orange;
                                                    i.ImageIndex = 2;
                                                }
                                                foreach (Match m4 in Regex.Matches(Teamsheet, @"<div.*?>Barred members</div>.*?<a.*?href=""\S+?/player/(\d+)/"">(.+?)</a>", RegexOptions.Singleline))
                                                {
                                                    if(m4.Groups[1].Value == m2.Groups[2].Value)
                                                    {
                                                        //ids match
                                                        i.BackColor = Color.Red;
                                                        i.ImageIndex = 2;
                                                    }
                                                }
                                                
                                            }
                                        }
                                }
                            }
                        }
                        team++;
                    }
                }


                string bla = "http://www.esl.eu/de/search/?type=gameaccount&query=";
                string resultRegex = @">Search results</div>.*?<a href="".*?/player/(.*?)/"">(.*?)</a>";

                
                foreach (ListViewItem i in PlayerList.Items)
                {
                    if (i.SubItems[3].Tag != null)
                        continue;
                    ParseStatusText.Text = String.Format(lang.ParsingPlayer, i.SubItems[1].Text);
                    HTML = ESLHelpers.GetHTML(bla + i.SubItems[1].Text, string.Empty);
                    Trace.WriteLine(HTML);
                    Match m = Regex.Match(HTML, resultRegex, RegexOptions.Singleline);
                    if (m.Success)
                    {
                        //Player found @ ESL
                        foundusers++;
                        i.SubItems[3].Text = m.Groups[2].Value;
                        i.SubItems[3].Tag = m.Groups[1].Value;
                        if (!string.IsNullOrEmpty(m_Archive.Matchlink))
                        {
                            bool aeqfound = false;
                            foreach (Match m4 in AeqRegex)
                            {
                                if (m4.Groups[1].Value == m.Groups[1].Value)
                                {
                                    //ids match
                                    aeqfound = true;
                                }
                            }
                            if (!aeqfound)
                            {
                                i.BackColor = Color.Orange;
                                i.ImageIndex = 2;
                            }
                        }
                    }
                }

        
            
                if (PlayerList.Items.Count > 0)
                {
                    //splitContainer1.Panel2Collapsed = false;
                    requestMatchmediaToolStripMenuItem.Visible = true;
                    if (!tabControl1.TabPages.Contains(tabPlayers))
                        tabControl1.TabPages.Add(tabPlayers);
                }
                else if (tabControl1.TabPages.Contains(tabPlayers))
                    tabControl1.TabPages.Remove(tabPlayers);
                    //splitContainer1.Panel2Collapsed = true;
                ParseStatusText.Text = String.Format(lang.ParseResult, foundusers);
                //ParseStatusText.Visible = false;
                //ParseProgress.Visible = false
        }*/

        private void FormUpload_Load(object sender, EventArgs e)
        {
            if (File.Exists("developer.secret"))
                return;
#if !DEBUG
            if (m_Cookie == string.Empty)
            {
                MessageBox.Show("You must be logged in in order to use the automatic upload!");
                this.Close();
            }
#endif
        }

        /*private void AddFileToList(XPTable.Models.TableModel tm, string s, bool select)
        {
            FileInfo file = new FileInfo(s);
            if (!file.Exists)
                return;
            string name = Regex.Replace(Path.GetFileNameWithoutExtension(s), @"_\d{2}.\d{2}.\d{4}_\d{2}-\d{2}-\d{2}$", String.Empty);

            Row r = new Row();
            
            r.Cells.Add(new Cell(string.Empty, select));
            r.Cells.Add(new Cell(string.Empty, lang.check16));

            r.Cells[r.Cells.Count - 1].ImageSizeMode = ImageSizeMode.ScaledToFit;
            r.Cells.Add(new Cell(name, lang.about_16));
            //ListViewItem i = new ListViewItem(name);
            r.Cells[r.Cells.Count - 1].Tag = file;
            
            //i.ToolTipText = Path.GetFileName(s);
            r.Cells.Add(new Cell(getFormattedKiloBytes(file.Length) + " kB"));

            r.Cells.Add(new Cell()); //Status 2
            r.Cells.Add(new Cell()); //Progress 3
            r.Cells.Add(new Cell()); //Speed 4
            r.Cells.Add(new Cell()); //Time Remaining 5
            string ext = Path.GetExtension(s).ToLower();
            
            tm.Rows.Add(r);
        }*/

        public string getFormattedKiloBytes(long Bytes)
        {
            StringBuilder b = new StringBuilder();
            b.Append(Math.Round(Bytes / (double)1000, 0).ToString());
            int sl = b.Length;
            for (int i = sl; i > 0; i--)
            {
                if (sl - i > 0 && (sl - i) % 3 == 0)
                    b.Insert(i, ".");
            }
            return b.ToString();
        }

        

        

        private void FormUpload_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (m_Archive.UploadsRunning > 0)
            {
                if (MessageBox.Show(this, lang.QuitQuestion, lang.AreYouSure, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                    m_Archive.CancelUploads();
                else
                    e.Cancel = true;
            }
        }

        /*private void PlayerList_DoubleClick(object sender, EventArgs e)
        {
            foreach(ListViewItem i in PlayerList.SelectedItems)
            {
                if (i.SubItems[3].Tag != null)
                    Process.Start("http://www.esl.eu/player/" + (string)i.SubItems[3].Tag + "/");
            }
        }*/

        /*private void viewPlayersProfileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem i in PlayerList.SelectedItems)
            {
                if (i.SubItems[3].Tag != null)
                    Process.Start("http://www.esl.eu/player/" + (string)i.SubItems[3].Tag + "/");
            }
        }*/

        /*private void requestDemoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using(FormDemoRequest r = new FormDemoRequest())
            {
                r.ShowDialog(this, PlayerList.Items,m_Archive.Matchlink, MapsPlayed);
            }
        }*/

        private void startUploadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //if (lwFileList.CheckedItems.Count <= 0)
                //return;
            startUploadToolStripMenuItem.Enabled = false;
            startUploadToolStripMenuItem1.Visible = false;
            cancelAllUploadsToolStripMenuItem.Visible = true;
            cancelSelectedUploadsToolStripMenuItem.Visible = true;
            

            cbUpload.Enabled = false;
            foreach (Row row in xpFiles.TableModel.Rows)
            {
                //row.Cells[0].Enabled = false;
                if (!row.Cells[0].Checked)
                    continue;
                m_Archive.StartUpload((MatchFile)row.Tag);
                row.Editable = false;
            }
            /*foreach (ListViewItem i in lwFileList.CheckedItems)
            {
                UncompressedFile f = new UncompressedFile((string)i.SubItems[0].Tag, i.Text);
                i.Tag = f;
                up.AddFile(f);
            }*/
            //lwFileList.CheckBoxes = false;
            //UploadProgress.Visible = true;
            UploadStatusText.Visible = true;
            UploadStatusText.Text = "Uploading ...";
            //up.Start();
            //uptimer.Enabled = true;
        }

        private void changeMatchlinkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (FormEditString f = new FormEditString())
            {
                m_Archive.Matchlink = f.ShowDialog(this, m_Archive.Matchlink);
            }
            this.Text = m_Archive.Matchlink;
            //up.MatchURL = m_Archive.Matchlink;
        }

        private void lwFileList_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.None;
        }

        private void lwFileList_DragDrop(object sender, DragEventArgs e)
        {
            Array a = (Array)e.Data.GetData(DataFormats.FileDrop);
            if (a != null)
            {
                for (int i = 0; i < a.Length; i++)
                {
                    string s = a.GetValue(i).ToString();
                    //AddFileToList(xpFiles.TableModel, s, true);
                    MatchFile newfile = new MatchFile(s);
                    m_Archive.AddFile(newfile);
                    Row r = getFileRow(newfile);
                    r.Cells[0].Checked = true;
                    xpFiles.TableModel.Rows.Add(r);
                }
            }
            
        }

        private void checkPlayersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartParser();
        }

        private void FormUpload_FormClosed(object sender, FormClosedEventArgs e)
        {
            bool retry = true;
            int retries = 0;
            if (!string.IsNullOrEmpty(m_Archive.Filename))
                while (retry)
                {
                    try
                    {
                        m_Archive.WriteArchiveDetails();
                        retry = false;
                    }
                    catch (Exception ex)
                    {
                        retries++;
                        if (retries > 1)
                            retry = MessageBox.Show(this, ex.Message, "Error writing archive!", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1) == DialogResult.Retry;
                    }
                }
                
            Properties.Settings.Default.UploadWindowSize = this.Size;
            Properties.Settings.Default.UploadWindowPos = this.DesktopLocation;
            this.Dispose();
        }

        private void FormUpload_Shown(object sender, EventArgs e)
        {
            this.Activate();
#if !DEBUG || TEST_PLAYERPARSING
            StartParser();
#endif
        }

        private void StartParser()
        {
            WorkProgress.Visible = true;
            ParseStatusText.Text = "Parsing website";
            ParseStatusText.Visible = true;
            Parser.RunWorkerAsync();
        }

        private void updateMatchInformationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                MatchInfoUpdater.RunWorkerAsync();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            WorkProgress.Visible = true;
        }

        private void MatchInfoUpdater_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (this == null || !this.Visible)
                return;
            if (e.Error != null)
            {
                if (e.Error is System.Net.WebException)
                    MessageBox.Show(e.Error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                    MessageBox.Show(e.Error.StackTrace, e.Error.Message);
            }
            WorkProgress.Visible = false;
            RefreshView();
        }

        private void MatchInfoUpdater_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                m_Archive.UpdateDetailsFromWeb(m_Cookie,MatchInfoFlags.MapInfo | MatchInfoFlags.ScoreInfo);
            }
            catch
            {
                
            }
        }

        private void Logo_Click(object sender, EventArgs e)
        {
            Control logo = sender as Control;

            if (logo.Tag != null && logo.Tag is string && !string.IsNullOrEmpty((string)logo.Tag))
            {
                try
                {
                    Process.Start((string)logo.Tag);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.StackTrace, ex.Message);
                }
            }

        }

        private void Parser_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                WorkProgress.Visible = false;
                ParseStatusText.Text = "Parser idle.";
                ParseStatusText.Visible = false;
                RefreshView();
                UpdateStats(m_Archive.Players);
            }
            catch{}
            if (e.Error != null)
                MessageBox.Show(e.Error.StackTrace, e.Error.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void xpFiles_BeginEditing(object sender, XPTable.Events.CellEditEventArgs e)
        {
            if (e.Column == 2)
            {
                ((ComboBoxCellEditor)e.Editor).MaxDropDownItems = 10;
                ((ComboBoxCellEditor)e.Editor).DropDownStyle = DropDownStyle.DropDown;
                ((ComboBoxCellEditor)e.Editor).Items.Clear();
                foreach (string s in Properties.Settings.Default.PredefinedFilenames)
                    ((ComboBoxCellEditor)e.Editor).Items.Add(s);
                ((ComboBoxCellEditor)e.Editor).Items.Add(Properties.Settings.Default.AequitasTitle);
            }
        }

        private void xpFiles_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
                xpFiles.TableModel.Rows.RemoveRange(xpFiles.SelectedItems);
        }

        private void xpFiles_EditingStopped(object sender, XPTable.Events.CellEditEventArgs e)
        {
            if (e.Column == 2)
            {
                ((MatchFile)e.Cell.Row.Tag).TargetName = (string)((ComboBoxCellEditor)e.Editor).Text;
            }
        }

        private void viewESLProfileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach(Row r in xpStatistics.SelectedItems)
            {
                if (r.Cells[2].Tag != null)
                    try { Process.Start("http://www.esl.eu/player/" + (string)r.Cells[2].Tag + "/"); }
                    catch { }
                else
                    MessageBox.Show("No ESL account associated with this player!");
                    
            }
        }

        private void cancelAllUploadsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_Archive.CancelUploads();
        }

        private void cancelSelectedUploadsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Row r in xpFiles.SelectedItems)
                ((MatchFile)r.Tag).CancelUpload();
        }

        private void xpFiles_DoubleClick(object sender, EventArgs e)
        {
            foreach (Row r in xpFiles.SelectedItems)
                try
                {
                    MatchFile f = r.Tag as MatchFile;
                    if (f.IsArchived)
                        MessageBox.Show("You can't view archived filecontents (yet)!");
                    else
                        Process.Start(f.Filename);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
        }

        private void createArchiveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Row r in xpFiles.TableModel.Rows)
                if (r.Cells[0].Checked)
                    ((MatchFile)r.Tag).AddToArchive = true;
            using (FormCreateArchive f = new FormCreateArchive(m_Archive))
                f.ShowDialog();
        }
        
    }
    public enum ParseStatus
    {
        Init
    }
    public struct ParseData
    {
        public ConsoleEventItemCollection Events;
        //public 
    };
}